package me.zhengjie.modules.quartz.task;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.fund.domain.FundNetValue;
import me.zhengjie.modules.fund.reptile.FundCrawler;
import me.zhengjie.modules.fund.service.FundNetValueService;
import me.zhengjie.modules.fund.service.UserFundService;
import me.zhengjie.modules.fund.service.dto.UserFundDto;
import me.zhengjie.modules.fund.service.dto.UserFundQueryCriteria;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.List;

@Slf4j
@Component
public class UserFundHistoryNetValueSyncTask {
    @Resource
    private UserFundService userFundService;

    @Resource
    private FundNetValueService fundNetValueService;

    @Resource
    private FundCrawler fundCrawler;

    public void run() throws ParseException {
        int pageNum = 0;
        int pageSize = 100;
        Page<UserFundDto> pageUserFunds;
        do {
            PageRequest page = PageRequest.of(pageNum, pageSize, Sort.Direction.DESC, "id");
            pageUserFunds = userFundService.queryAll(new UserFundQueryCriteria(), page);

            List<UserFundDto> userFunds = pageUserFunds.getContent();
            try {
                syncFundNetValues(userFunds);
            } catch (ParseException e) {
                log.error("同步基金净值失败", e);
                throw e;
            }
            pageNum++;
        } while (pageUserFunds.hasNext());
    }

    public void syncFundNetValues(List<UserFundDto> userFundDtos) throws ParseException {
        if (CollectionUtils.isEmpty(userFundDtos)) {
            return;
        }
        for (UserFundDto userFund : userFundDtos) {
            if ("合计".equals(userFund.getFundCode())) {
                continue;
            }
            log.info("开始同步基金：{} 名称:{} 历史净值数据", userFund.getFundCode(), userFund.getFundName());
            // 第一次添加的基金，直接把历史数据全部同步过来
            initFundNetValue(userFund.getFundCode());
            log.info("结束同步基金：{} 名称:{} 历史净值数据", userFund.getFundCode(), userFund.getFundName());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void initFundNetValue(String code) throws ParseException {
        int page = 1;
        List<FundNetValue> fundNetValues;
        DateTime start = DateUtil.parse("2000-01-01", "yyyy-MM-dd");
        do {
            fundNetValues = fundCrawler.findFundNetValueByPage(code, PageRequest.of(page, 20), start);
            fundNetValueService.saveAll(fundNetValues);
            page++;
        } while (!CollectionUtil.isEmpty(fundNetValues));
    }
}
